#pragma once
#include <iostream>
#include <string>

#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

static std::string cwd = "/";

class Daemon
{
public:
    Daemon(bool nochdir, bool noclose)
        : _nochdir(nochdir)
        , _noclose(noclose)
    {
        //1. 忽略可能引起进程异常退出的信号
        signal(SIGCHLD, SIG_IGN);
        signal(SIGPIPE, SIG_IGN);
        //2. 不让自己成为组长，创建子进程，让父进程退出，子进程一定不是该进程组的组长，父进程才是
        if(fork() > 0) exit(0);
        //3. 将子进程设置为独立会话
        setsid();
        //4. 是否更改当前的cwd到根目录
        if(_nochdir)
        {
            chdir(cwd.c_str());
        }
        //5. 是否需要直接关闭stdin、stdout、stderr
        if(_noclose)
        {
            close(0);
            close(1);
            close(2);
        }
        else //不直接关闭，将其重定向到/dev/null文件中
        {
            int fd = open("/dev/null", O_RDWR);
            dup2(fd, 0);
            dup2(fd, 1);
            dup2(fd, 2);
        }
    }
    ~Daemon()
    {}
private:
    bool _nochdir;
    bool _noclose;
};